﻿using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System;
using System.Threading.Tasks;
using VisionCloud.Domain.Common;
using VisionCloud.Domain.DtoModel.Applet.RequestDto;
using VisionCloud.Domain.DtoModel.Applet.ResponseDto;
using VisionCloud.Domain.Filters;
using VisionCloud.MeasureIMCore;
using VisionCloud.Utility;
using VisionCloud.Utility.Redis;
using static VisionCloud.Core.Model.Sys.SysUser;

namespace VisionCloud.Api.Controllers.Applet
{
    /// <summary>
    /// WebSocket
    /// </summary>
    [SystemModule("小程序模块")]
    [ApiAuthorize(PolicyEnum.RequireRolePermission)]
    [ApiVersion("1.0")]
    [Route("api/applet/[controller]/[Action]")]
    [ApiExplorerSettings(GroupName = "小程序模块")]
    public class WebSocketController : ApiBaseController
    {
        private static readonly Guid agentSocketId = ConfigHelper.GetValue<Guid>("MeasureIM:GPTAgentSocketId");

        /// <summary>
        /// 获取websocket服务器连接url.连接之前必须请求此接口
        /// </summary>
        /// <returns>websocket服务器连接url</returns>
        [SwaggerResponse(0, "获取详情数据的字段：Result", typeof(ApiResultBase<WebsocketConnetInfoDto>))]
        [HttpPost]
        public async Task<ApiResult> PreConnect() =>
            await Task.Run(() =>
            {
                var socketId = TokenModel.UserType == (int)EnumUserType.游客账号 ? Guid.NewGuid() : TokenModel.YunUserGuid;
                var wsserver = ImHelper.PrevConnectServer(socketId, "UserId", ConfigHelper.GetValue<bool>("MeasureIM:IsWSS"));
                return new ApiResult(code: AjaxCode.Success).SetData(new WebsocketConnetInfoDto { SocketId = socketId, Url = wsserver });
            });

        /// <summary>
        /// 提问。可以不带诊断ID。
        /// 会进行安全检测
        /// </summary>
        [HttpPost]
        public async Task<ApiResult> AskQuestion(QuestionDto question)
        {
            question.SocketId ??= TokenModel.Id;

            var apiResult = new ApiResult();
            var askLockKey = $"Applet:{question.SocketId}:LockAsking";//Redis分布式锁
            var askCachedKey = $"Applet:{question.SocketId}:QuestionAsking";
            if (!await RedisHelper.Instance.ExistsAsync(askCachedKey) && await RedisHelper.Instance.LockTakeAsync(askLockKey, Environment.MachineName, TimeSpan.FromMilliseconds(1000)))
            {
                try
                {
                    if (!await RedisHelper.Instance.ExistsAsync(askCachedKey))
                    {
                        RedisHelper.Instance.SetValue(askCachedKey, string.Empty, TimeSpan.FromSeconds(50));
                        var openid = TokenModel.WxOpenId;

                        var (IsPass, _) = await WeChartApiHelper.WxMsgSecCheck(question.Content, openid);
                        if (IsPass)
                        {
                            apiResult.Code = AjaxCode.Success;
                            var requestdto = new RequetQuestionDto(question);
                            ImHelper.SendMessage(question.SocketId.Value, new[] { agentSocketId }, requestdto);
                        }
                        else
                            apiResult.Message = "识别到发送内容可能不合规，请换个问题再试试！";

                        return apiResult;
                    }
                }
                finally
                {
                    await RedisHelper.Instance.LockReleaseAsync(askLockKey, Environment.MachineName).ConfigureAwait(false);
                }
            }

            apiResult.Message = "您的提问太快了，请休息一下稍后再试。";
            return apiResult;
        }

        /// <summary>
        /// 提问，测试专用，测完删除此方法
        /// </summary>
        /// <param name="question"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> AskQuestionForTest(QuestionDto question)
        {
            question.SocketId ??= TokenModel.Id;

            var apiResult = new ApiResult();
            var askLockKey = $"Applet:{question.SocketId}:LockAsking";//Redis分布式锁
            var askCachedKey = $"Applet:{question.SocketId}:QuestionAsking";
            if (!await RedisHelper.Instance.ExistsAsync(askCachedKey) && await RedisHelper.Instance.LockTakeAsync(askLockKey, Environment.MachineName, TimeSpan.FromMilliseconds(1000)))
            {
                try
                {
                    if (!await RedisHelper.Instance.ExistsAsync(askCachedKey))
                    {
                        RedisHelper.Instance.SetValue(askCachedKey, string.Empty, TimeSpan.FromSeconds(50));

                        var requestdto = new RequetQuestionDto(question);
                        ImHelper.SendMessage(question.SocketId.Value, new[] { agentSocketId }, requestdto);
                        apiResult.Code = AjaxCode.Success;

                        return apiResult;
                    }
                }
                finally
                {
                    await RedisHelper.Instance.LockReleaseAsync(askLockKey, Environment.MachineName).ConfigureAwait(false);
                }
            }

            apiResult.Message = "您的提问太快了，请休息一下稍后再试。";
            return apiResult;
        }
    }
}